﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Thor.Domain;

namespace Thor.Domain.Configuration
{
    public class AdministratorAccountManager
    {
        #region Fields

        private IAdministratorAccountRepository _administratorAccountRepository = null;
        private List<AdministratorAccount> _administrators = null;

        #endregion

        #region Constructors

        public AdministratorAccountManager(IAdministratorAccountRepository administratorAccountRepository)
        {
            _administratorAccountRepository = administratorAccountRepository;
        }

        #endregion

        #region Properties

        /// <summary>
        /// List of people who can administer the worker role.
        /// </summary>
        public List<AdministratorAccount> Administrators
        {
            get
            {
                if (_administrators == null)
                    _administrators = _administratorAccountRepository.Fetch();

                if (_administrators == null)
                    _administrators = new List<AdministratorAccount>();

                return _administrators;
            }
            set { _administrators = value; }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Inserts an administrator.
        /// </summary>
        /// <param name="administratorAccount"></param>
        public void Insert(AdministratorAccount administratorAccount)
        {
            if (administratorAccount.Id == Guid.Empty)
                administratorAccount.Id = Guid.NewGuid();

            _administratorAccountRepository.Insert(administratorAccount);
        }

        /// <summary>
        /// Updates an administrator.
        /// </summary>
        /// <param name="administratorAccount"></param>
        public void Update(AdministratorAccount administratorAccount)
        {
            _administratorAccountRepository.Update(administratorAccount);
        }

        /// <summary>
        /// Deletes the administrator.
        /// </summary>
        /// <param name="administratorAccount"></param>
        public void Delete(AdministratorAccount administratorAccount)
        {
            _administratorAccountRepository.Delete(administratorAccount);
        }

        /// <summary>
        /// Gets a concrete implementation of IAdministratorAccountRepository.
        /// </summary>
        /// <param name="assemblyPath">Full path to the assembly.</param>
        /// <param name="typeName">Full type name of the type in the assembly that implements IAdministratorAccountRepository.</param>
        /// <returns></returns>
        public static IAdministratorAccountRepository GetRepository(string assemblyPath, string typeName, Dictionary<string, object> repositoryParameters)
        {
            //Load the assembly from the specified path.
            Assembly assembly = Assembly.LoadFile(assemblyPath);

            //Load the type
            Type type = assembly.GetType(typeName);

            //Get the constructor
            Type[] constructorTypes = new Type[1];
            constructorTypes[0] = typeof(Dictionary<string, object>);
            ConstructorInfo constructorInfo = type.GetConstructor(constructorTypes);

            //Invoke the constructor and return a new instance
            if (constructorInfo != null)
                return constructorInfo.Invoke(new object[] { repositoryParameters }) as IAdministratorAccountRepository;

            return null;
        }

        #endregion
    }
}
